package com.xb.ai.controller;


import cn.dev33.satoken.stp.StpUtil;
import com.xb.ai.annotation.Login;
import com.xb.ai.constant.ErrorMessage;
import com.xb.ai.common.Result;
import com.xb.ai.exception.BusinessException;
import com.xb.ai.repository.ChatHistoryRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;

import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID_KEY;

@RequiredArgsConstructor
@RestController
@RequestMapping("/ai")
public class ChatController {

    private final ChatClient chatClient;

    private final ChatHistoryRepository chatHistoryRepository;

    @Login
    @GetMapping(value = "/chat",
            produces = MediaType.TEXT_EVENT_STREAM_VALUE + ";charset=UTF-8")
    public Flux<String> chat(
            @RequestParam("text") String text,
            @RequestParam("chatId") Long chatId,
            @RequestParam("userId") Long userId) {
        verifyUserLogin(userId);
        // 1.保存会话id
        chatHistoryRepository.save(chatId, userId, text);
        // 2.请求模型
        return textChat(text, chatId);
    }

    private Flux<String> textChat(String text, Long chatId) {
        return chatClient.prompt()
                .user(text)
                .advisors(a -> a.param(CHAT_MEMORY_CONVERSATION_ID_KEY, chatId))
                .stream()
                .content();
    }

    /**
     * 根据chatId删除指定对话
     */
    @DeleteMapping("/chat/delete/{chatId}")
    public Result<String> deleteChat(@PathVariable("chatId") Long chatId,
                                     @RequestParam("userId") Long userId) {
        verifyUserLogin(userId);
        boolean delete = chatHistoryRepository.delete(chatId,userId);
        if (!delete) {
            return Result.error("删除失败");
        }
        return Result.success("删除成功");
    }

    /**
     * 验证用户是否登录
     * @param userId 用户传的id
     */
    public void verifyUserLogin(Long userId){
        if (userId == null) {
            throw new BusinessException(ErrorMessage.NOT_LOGIN_ERROR);
        }
        long userLoginId = StpUtil.getLoginIdAsLong();
        if (userId != userLoginId) {
            throw new BusinessException(ErrorMessage.NO_AUTH_ERROR);
        }
    }
}
